package com.zt.fbg.filter;

import io.opentracing.util.GlobalTracer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.net.URI;
import java.util.UUID;

@Component
public class LoggingFilter implements GlobalFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
    public static String LOG_TRACE_ID = "LOG_TRACE_ID";
    public static String TRACE_ID_HEADER = "TRACE-ID-HEADER";
    private static final String START_TIME = "startTime";
    private static final String Client_IP = "Client-IP";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        //链路追踪id
        String traceId = getTraceId();
        MDC.put(LOG_TRACE_ID, traceId);
        exchange.getAttributes().put(START_TIME, System.currentTimeMillis());
        exchange.getAttributes().put(LOG_TRACE_ID, traceId);
        ServerHttpRequest request=exchange.getRequest();

        logger.info("【进入网关】,网关链路追踪id：{}，客户请求IP：{}，请求URL：{}",traceId,request.getRemoteAddress(),request.getURI());

        GlobalTracer.get().activeSpan().setOperationName(request.getURI().toString());

        ServerWebExchange build=exchange.mutate().request(request).build();
        Mono<Void> filter = chain.filter(build);
        // 这个 .then 是等到其它 Mono(filter) 执行完毕才会执行，比如会等到 JwtAuthFilter 执行完毕，才会返回这里
        return chain.filter(build).then( Mono.fromRunnable(() -> {

            Long startTime = exchange.getAttribute(START_TIME);
            String logTraceId=exchange.getAttribute(LOG_TRACE_ID);
            URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
            String appKey =exchange.getRequest().getHeaders().getFirst("appKey");
            String appToken =exchange.getRequest().getHeaders().getFirst("appToken");
            int responseCode=exchange.getResponse().getStatusCode().value();
            Long executeTime = (System.currentTimeMillis() - startTime);

            logger.info("【网关执行完成】,网关链路追踪id：{},记录执行时间，filter执行完成，转发路径：{};返回码：{};appKey={};appToken={};执行时间：{}ms",logTraceId,url,responseCode,appKey,appToken,executeTime);
        }));
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }

    private String getTraceId() {
        String traceId = GlobalTracer.get().scopeManager().activeSpan().context().toTraceId();
        return StringUtils.isEmpty(traceId)? UUID.randomUUID().toString().replaceAll("-", ""):traceId;
    }
}
